#!/bin/bash

set -e

# 集成测试脚本 - 综合测试智能快照器功能

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 默认配置
SNAPSHOTTER_NAME="smart"
TEST_RESULTS_DIR="./integration-test-results"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")

# 创建结果目录
mkdir -p "$TEST_RESULTS_DIR"

# 记录日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$TEST_RESULTS_DIR/integration-test-$TIMESTAMP.log"
}

error() {
    echo -e "${RED}[ERROR] $1${NC}" | tee -a "$TEST_RESULTS_DIR/integration-test-$TIMESTAMP.log"
}

success() {
    echo -e "${GREEN}[SUCCESS] $1${NC}" | tee -a "$TEST_RESULTS_DIR/integration-test-$TIMESTAMP.log"
}

info() {
    echo -e "${BLUE}[INFO] $1${NC}" | tee -a "$TEST_RESULTS_DIR/integration-test-$TIMESTAMP.log"
}

warning() {
    echo -e "${YELLOW}[WARNING] $1${NC}" | tee -a "$TEST_RESULTS_DIR/integration-test-$TIMESTAMP.log"
}

# 测试结果记录
declare -A TEST_RESULTS

# 测试函数：检查快照器状态
test_snapshotter_status() {
    log "测试1: 检查快照器状态"

    if ctr plugin ls | grep -q "$SNAPSHOTTER_NAME.*ok"; then
        success "快照器 $SNAPSHOTTER_NAME 状态正常"
        TEST_RESULTS["snapshotter_status"]="PASS"
        return 0
    else
        error "快照器 $SNAPSHOTTER_NAME 状态异常"
        TEST_RESULTS["snapshotter_status"]="FAIL"
        return 1
    fi
}

# 测试函数：基本容器创建和删除
test_basic_container_operations() {
    log "测试2: 基本容器操作"

    local test_passed=true
    local container_name="integration-test-basic"

    # 测试容器创建
    info "创建测试容器..."
    if timeout 60 ctr run --snapshotter "$SNAPSHOTTER_NAME" --rm docker.io/library/alpine:latest "$container_name" echo "test" > /dev/null 2>&1; then
        success "容器创建成功"
    else
        error "容器创建失败"
        test_passed=false
    fi

    if [ "$test_passed" = true ]; then
        TEST_RESULTS["basic_operations"]="PASS"
    else
        TEST_RESULTS["basic_operations"]="FAIL"
    fi

    return $([ "$test_passed" = true ])
}

# 测试函数：快照创建和恢复
test_snapshot_creation_and_restore() {
    log "测试3: 快照创建和恢复"

    local test_passed=true
    local container_name="integration-test-snapshot"
    local snapshot_name="test-snapshot"

    # 创建容器
    info "创建测试容器..."
    if ! ctr run --snapshotter "$SNAPSHOTTER_NAME" -d docker.io/library/alpine:latest "$container_name" sleep 300 > /dev/null 2>&1; then
        error "测试容器创建失败"
        TEST_RESULTS["snapshot_operations"]="FAIL"
        return 1
    fi

    # 创建快照
    info "创建快照..."
    if ctr snapshot --snapshotter "$SNAPSHOTTER_NAME" create "$snapshot_name" "${container_name}-snapshot"; then
        success "快照创建成功"
    else
        error "快照创建失败"
        test_passed=false
    fi

    # 从快照恢复容器
    if [ "$test_passed" = true ]; then
        info "从快照恢复容器..."
        if ctr run --snapshotter "$SNAPSHOTTER_NAME" --rm --snapshot "${container_name}-snapshot" docker.io/library/alpine:latest "${container_name}-restored" echo "restored" > /dev/null 2>&1; then
            success "快照恢复成功"
        else
            error "快照恢复失败"
            test_passed=false
        fi
    fi

    # 清理
    ctr container rm "$container_name" > /dev/null 2>&1 || true
    ctr snapshot --snapshotter "$SNAPSHOTTER_NAME" rm "${container_name}-snapshot" > /dev/null 2>&1 || true
    ctr snapshot --snapshotter "$SNAPSHOTTER_NAME" rm "$snapshot_name" > /dev/null 2>&1 || true

    if [ "$test_passed" = true ]; then
        TEST_RESULTS["snapshot_operations"]="PASS"
    else
        TEST_RESULTS["snapshot_operations"]="FAIL"
    fi

    return $([ "$test_passed" = true ])
}

# 测试函数：多层镜像处理
test_multi_layer_images() {
    log "测试4: 多层镜像处理"

    local test_passed=true
    local container_name="integration-test-multilayer"

    # 使用多层镜像（如nginx）
    info "测试多层镜像..."
    if timeout 60 ctr run --snapshotter "$SNAPSHOTTER_NAME" --rm docker.io/library/nginx:latest "$container_name" nginx -t > /dev/null 2>&1; then
        success "多层镜像处理成功"
    else
        error "多层镜像处理失败"
        test_passed=false
    fi

    if [ "$test_passed" = true ]; then
        TEST_RESULTS["multi_layer"]="PASS"
    else
        TEST_RESULTS["multi_layer"]="FAIL"
    fi

    return $([ "$test_passed" = true ])
}

# 测试函数：并发操作
test_concurrent_operations() {
    log "测试5: 并发操作"

    local test_passed=true
    local pids=()
    local success_count=0
    local failure_count=0

    info "启动并发容器创建..."

    # 并发创建5个容器
    for i in {1..5}; do
        (
            if timeout 60 ctr run --snapshotter "$SNAPSHOTTER_NAME" --rm docker.io/library/alpine:latest "concurrent-test-$i" echo "concurrent $i" > /dev/null 2>&1; then
                echo "SUCCESS"
            else
                echo "FAILED"
            fi
        ) &
        pids+=($!)
    done

    # 等待所有并发操作完成
    for pid in "${pids[@]}"; do
        if wait "$pid"; then
            ((success_count++))
        else
            ((failure_count++))
        fi
    done

    info "并发操作结果: 成功 $success_count, 失败 $failure_count"

    if [ $failure_count -eq 0 ]; then
        success "并发操作测试通过"
        TEST_RESULTS["concurrent_operations"]="PASS"
    else
        error "并发操作测试失败"
        TEST_RESULTS["concurrent_operations"]="FAIL"
        test_passed=false
    fi

    return $([ "$test_passed" = true ])
}

# 测试函数：资源清理
test_resource_cleanup() {
    log "测试6: 资源清理"

    local test_passed=true
    local container_name="integration-test-cleanup"

    # 创建容器
    info "创建测试容器..."
    ctr run --snapshotter "$SNAPSHOTTER_NAME" -d docker.io/library/alpine:latest "$container_name" sleep 300 > /dev/null 2>&1

    # 获取快照列表
    local snapshots_before=$(ctr snapshot --snapshotter "$SNAPSHOTTER_NAME" ls | wc -l)

    # 删除容器
    info "删除容器..."
    if ctr container rm "$container_name" > /dev/null 2>&1; then
        success "容器删除成功"
    else
        error "容器删除失败"
        test_passed=false
    fi

    # 检查资源清理
    sleep 2  # 等待清理完成
    local snapshots_after=$(ctr snapshot --snapshotter "$SNAPSHOTTER_NAME" ls | wc -l)

    if [ "$snapshots_before" -gt "$snapshots_after" ]; then
        success "资源清理正常"
    else
        warning "资源清理可能存在问题"
    fi

    if [ "$test_passed" = true ]; then
        TEST_RESULTS["resource_cleanup"]="PASS"
    else
        TEST_RESULTS["resource_cleanup"]="FAIL"
    fi

    return $([ "$test_passed" = true ])
}

# 测试函数：错误处理
test_error_handling() {
    log "测试7: 错误处理"

    local test_passed=true

    # 测试1: 使用不存在的镜像
    info "测试不存在的镜像..."
    if ctr run --snapshotter "$SNAPSHOTTER_NAME" --rm docker.io/library/nonexistent:latest error-test echo "test" > /dev/null 2>&1; then
        error "应该失败但没有失败"
        test_passed=false
    else
        success "正确处理了不存在的镜像"
    fi

    # 测试2: 无效的快照器配置
    info "测试无效配置..."
    if timeout 10 ctr run --snapshotter "invalid-snapshotter" --rm docker.io/library/alpine:latest invalid-test echo "test" > /dev/null 2>&1; then
        error "应该失败但没有失败"
        test_passed=false
    else
        success "正确处理了无效配置"
    fi

    if [ "$test_passed" = true ]; then
        TEST_RESULTS["error_handling"]="PASS"
    else
        TEST_RESULTS["error_handling"]="FAIL"
    fi

    return $([ "$test_passed" = true ])
}

# 性能基准测试
performance_benchmark() {
    log "性能基准测试"

    local container_name="perf-benchmark"
    local iterations=10
    local total_time=0

    info "运行 $iterations 次启动测试..."

    for i in $(seq 1 "$iterations"); do
        local start_time=$(date +%s.%N)

        if timeout 30 ctr run --snapshotter "$SNAPSHOTTER_NAME" --rm docker.io/library/alpine:latest "${container_name}-${i}" echo "benchmark" > /dev/null 2>&1; then
            local end_time=$(date +%s.%N)
            local duration=$(echo "$end_time - $start_time" | bc -l)
            total_time=$(echo "$total_time + $duration" | bc -l)

            info "第 $i 次: ${duration}s"
        else
            warning "第 $i 次测试失败"
        fi
    done

    local avg_time=$(echo "scale=3; $total_time / $iterations" | bc -l)
    info "平均启动时间: ${avg_time}s"

    # 记录性能数据
    cat > "$TEST_RESULTS_DIR/performance-benchmark-$TIMESTAMP.json" << EOF
{
    "timestamp": "$(date -Iseconds)",
    "test_type": "startup_time",
    "iterations": $iterations,
    "average_time": $avg_time,
    "total_time": $total_time
}
EOF

    TEST_RESULTS["performance_benchmark"]="PASS"
}

# 生成测试报告
generate_test_report() {
    log "生成测试报告..."

    local report_file="$TEST_RESULTS_DIR/integration-test-report-$TIMESTAMP.txt"
    local total_tests=0
    local passed_tests=0
    local failed_tests=0

    # 统计结果
    for result in "${TEST_RESULTS[@]}"; do
        ((total_tests++))
        if [ "$result" = "PASS" ]; then
            ((passed_tests++))
        else
            ((failed_tests++))
        fi
    done

    local success_rate=$(echo "scale=2; $passed_tests * 100 / $total_tests" | bc -l)

    cat > "$report_file" << EOF
=====================================
智能快照器集成测试报告
=====================================
测试时间: $(date)
快照器: $SNAPSHOTTER_NAME
总测试数: $total_tests
通过: $passed_tests
失败: $failed_tests
成功率: $success_rate%

详细结果:
EOF

    # 添加详细结果
    for test_name in "${!TEST_RESULTS[@]}"; do
        local status="${TEST_RESULTS[$test_name]}"
        local status_color=""

        if [ "$status" = "PASS" ]; then
            status_color="${GREEN}"
        else
            status_color="${RED}"
        fi

        echo "  $test_name: ${status_color}$status${NC}" >> "$report_file"
    done

    cat >> "$report_file" << EOF

测试日志: $TEST_RESULTS_DIR/integration-test-$TIMESTAMP.log
性能基准: $TEST_RESULTS_DIR/performance-benchmark-$TIMESTAMP.json

=====================================
EOF

    success "测试报告已生成: $report_file"

    # 显示报告摘要
    echo
    echo "集成测试摘要:"
    echo "==============="
    echo "总成功率: $success_rate% ($passed_tests/$total_tests)"
    echo
    echo "详细报告: $report_file"
}

# 清理函数
cleanup() {
    log "清理测试资源..."

    # 停止并删除所有测试容器
    local test_containers=$(ctr container ls | grep -E "(integration-test|concurrent-test|perf-benchmark|error-test|invalid-test)" | awk '{print $1}' || true)

    if [ -n "$test_containers" ]; then
        echo "$test_containers" | xargs -r ctr container rm -f > /dev/null 2>&1 || true
    fi

    # 清理测试快照
    local test_snapshots=$(ctr snapshot --snapshotter "$SNAPSHOTTER_NAME" ls | grep -E "(integration-test|concurrent-test|perf-benchmark|error-test|invalid-test)" | awk '{print $1}' || true)

    if [ -n "$test_snapshots" ]; then
        echo "$test_snapshots" | xargs -r ctr snapshot --snapshotter "$SNAPSHOTTER_NAME" rm > /dev/null 2>&1 || true
    fi

    success "清理完成"
}

# 主测试函数
main() {
    log "开始智能快照器集成测试"
    log "====================================="

    # 设置清理陷阱
    trap cleanup EXIT INT TERM

    # 运行各项测试
    test_snapshotter_status
    test_basic_container_operations
    test_snapshot_creation_and_restore
    test_multi_layer_images
    test_concurrent_operations
    test_resource_cleanup
    test_error_handling
    performance_benchmark

    # 生成测试报告
    generate_test_report

    log "集成测试完成"
    log "====================================="

    # 返回总体结果
    local failed_count=0
    for result in "${TEST_RESULTS[@]}"; do
        if [ "$result" != "PASS" ]; then
            ((failed_count++))
        fi
    done

    if [ $failed_count -eq 0 ]; then
        success "所有测试通过!"
        exit 0
    else
        error "$failed_count 项测试失败"
        exit 1
    fi
}

# 参数解析
while [[ $# -gt 0 ]]; do
    case $1 in
        --snapshotter)
            SNAPSHOTTER_NAME="$2"
            shift 2
            ;;
        --help)
            echo "用法: $0 [选项]"
            echo "选项:"
            echo "  --snapshotter NAME   快照器名称 (默认: smart)"
            echo "  --help               显示帮助信息"
            exit 0
            ;;
        *)
            error "未知参数: $1"
            exit 1
            ;;
    esac
done

# 运行主函数
main "$@"